use std::process::{Command};
use std::fs::{File, OpenOptions};
use std::io::{Read, Seek, SeekFrom};
use std::thread;
use std::time::Duration;

use encoding_rs::GBK;

use regex::Regex;

mod qqchat;

fn main(){

    println!("请输入发消息的对象类型：\n——0：好友\n——1：群聊");
    let mut choice = String::new();
    std::io::stdin().read_line(&mut choice).expect("读取失败！");
    let choice = choice.trim();


    match choice {
        "1" => {
            println!("请输入群号：");
        },
        _ => {
            println!("请输入好友QQ号：");
        }
    }

    loop{
        let mut target = String::new();
        std::io::stdin().read_line(&mut target).expect("读取输入失败");
        let target = target.trim();
        match target.parse::<i32>() {
            Ok(num) => {
                println!("即将向{}发送消息！", num);
                if let Err(e) = start_java(num, choice.to_string()){
                    println!("启动Java进程失败：{}", e);
                }
            },
            Err(_) => {
                println!("号码错误，请重新输入：");
            }
        }
    }
    
}

fn extract_player_message(input: &str) -> Option<(&str, &str)> {
    let re = Regex::new(r"<([^>]+)>([^\n]*)").unwrap();
    
    re.captures(input).map(|cap| {
        let name = cap.get(1).unwrap().as_str();
        let content = cap.get(2).unwrap().as_str().trim();
        (name, content)
    })
}



fn start_java(target: i32, mode: String) -> Result<(), Box<dyn std::error::Error>> {
    // // 获取用户输入的 JAR 文件路径
    // println!("请输入JAR文件的路径（也可将.jar文件拖入此窗口）：");
    // let mut jar_path = String::new();
    // std::io::stdin().read_line(&mut jar_path)?;
    // // 去除可能的换行符和前后空格
    // let jar_path = jar_path.trim();

    // // // 配置参数
    // let log_path = "output.log";

    // // 清空或创建日志文件
    // File::create(log_path)?;

    println!("请输入日志文件路径（也可直接拖入此窗口，一般以.txt，.log为后缀名）：");
    let mut log_path = String::new();
    std::io::stdin().read_line(&mut log_path)?;
    // 去除可能的换行符和前后空格
    let log_path = log_path.trim().to_string();

    // // 启动Java进程并重定向输出到文件
    // let mut child = Command::new("java")
    //     .arg("-jar")
    //     .arg(jar_path)
    //     .stdout(OpenOptions::new().append(true).create(true).open(log_path)?)
    //     .stderr(OpenOptions::new().append(true).create(true).open(log_path)?)
    //     .spawn()?;

    // 文件监控线程
    thread::spawn(move || {
        let mut file = match File::open(log_path) {
            Ok(f) => f,
            Err(e) => {
                eprintln!("无法打开日志文件: {}", e);
                return;
            }
        };

        let mut pos = 0;

        let mut first_run = true;

        loop {
            // // 检查进程是否还在运行
            // if let Ok(Some(_)) = child.try_wait() {
            //     println!("Java进程已结束");
            //     break;
            // }

            // 获取文件当前大小
            let curr_len = match file.metadata() {
                Ok(m) => m.len(),
                Err(e) => {
                    eprintln!("获取文件元数据失败: {}", e);
                    thread::sleep(Duration::from_millis(100));
                    continue;
                }
            };

            // 如果有新内容
            if curr_len > pos {
                // 定位到上次读取的位置
                if let Err(e) = file.seek(SeekFrom::Start(pos)) {
                    eprintln!("文件定位失败: {}", e);
                    thread::sleep(Duration::from_millis(100));
                    continue;
                }

                // 计算需要读取的字节数
                let read_size = curr_len - pos;
                let mut buffer = vec![0; read_size as usize];
                
                // 使用read而不是read_exact，因为read_exact在文件大小变化时可能失败
                match file.read(&mut buffer) {
                    Ok(n) if n > 0 => {

                        if first_run {
                            println!("已开始监控日志文件！");
                            first_run = false;
                            pos += n as u64;
                            continue;
                        }

                        let (cow, _encoding_used, had_errors) = GBK.decode(&buffer[..n]);
                        if had_errors {
                            eprintln!("解码过程中遇到非法GBK序列");
                        }

                        if let Some((name, content)) = extract_player_message(&cow.to_string()) {
                            if let Err(e) = qqchat::send_message_test(target, &format!("<{}> {}", name, content), &mode){
                                println!("发送消息失败：{}\n——请保证Napcat正确配置", e);
                            }
                        }
                        else {
                            println!("未匹配到玩家信息");
                        }
                        print!("Java输出：{}", cow);
                        pos += n as u64;
                    }
                    Ok(_) => {} // 读取了0字节
                    Err(e) => eprintln!("读取文件失败: {}", e),
                }
            }

            // 短暂休眠避免CPU占用过高
            thread::sleep(Duration::from_millis(200));
        }
    }).join().unwrap();

    Ok(())
}